// Copyright 2010 Keir Mierle. All rights reserved.

#include <iostream>
#include <gtest/gtest.h>

#include "gomoku.h"
#include "dfpns.h"

TEST(DFPNS, HarderProblem) {
  return;
  const char *str_board = 
    ". x o x x . o o \n"
    ". . o x . x x o \n"
    ". o . o o x o x \n"
    ". . o . x o x o \n"
    "x o x x x o o . \n"
    ". . o . x o x . \n"
    "o . . . o x . o \n"
    ". x . x . . x . \n";

  GomokuBoard board;
  board.FromString(str_board);

  uint64 explored;
  if (DFPNS(board, &explored)) {
    cout << "Black wins?\n";
  }
  cout << "Explored " << explored << "\n";
}

TEST(DFPNS, BlackCanWinOnFirstMove) {
  const char *str_board = 
    ". x x x x . o o \n"
    ". . o x . x x o \n"
    ". o . o o x o x \n"
    ". . o . x o x o \n"
    "x o x x x o o . \n"
    ". . o . x o x . \n"
    "o . . . o x . o \n"
    ". x . x . . x . \n";
  GomokuBoard board;
  board.FromString(str_board);
  uint64 explored;
  EXPECT_TRUE(DFPNS(board, &explored));
  cout << "Explored " << explored << "\n";
}

TEST(DFPNS, WhiteCanWinOnFirstMoveAndBlackCantBlock) {
  const char *str_board = 
    ". x x o x . o o \n"
    ". . o x . x x o \n"
    ". o o o o . o x \n"
    ". . o . x o x o \n"
    "x o x x x o o . \n"
    ". . o . x o x . \n"
    "o . . . o x . o \n"
    ". x . x . . x . \n";
  GomokuBoard board;
  board.FromString(str_board);
  uint64 explored;
  EXPECT_FALSE(DFPNS(board, &explored));
  cout << "Explored " << explored << "\n";
}

TEST(DFPNS, TrickyIWonder) {
  const char *str_board = 
    ". x x o x . o o \n"
    ". . o x . x x o \n"
    ". o . o o . o x \n"
    ". . o . x o x o \n"
    "x o x x x o o . \n"
    ". . o . x o x . \n"
    "o . . . o x . o \n"
    ". x . x . . x . \n";
  GomokuBoard board;
  board.FromString(str_board);
  uint64 explored;
  EXPECT_FALSE(DFPNS(board, &explored));
  cout << "Explored " << explored << "\n";
}

TEST(DFPNS, TrickyIWonder2) {
  const char *str_board = 
    ". x x o x . o o \n"
    ". . o x . x x o \n"
    ". o . o o . o x \n"
    ". . o . x o x o \n"
    "x o x x . . o . \n"
    ". . o . x o x . \n"
    "o . . . o x . o \n"
    ". x . x . . x . \n";
  GomokuBoard board;
  board.FromString(str_board);
  uint64 explored;
  EXPECT_FALSE(DFPNS(board, &explored));
  cout << "Explored " << explored << "\n";
}

TEST(DFPNS, TrickyIWonder3) {
  const char *str_board = 
    ". x x o x . o o \n"
    ". . o x . x x o \n"
    ". o . o . . o x \n"
    ". . o . x o x o \n"
    "x o x x . . o . \n"
    ". . o . x o x . \n"
    "o . . . o x . o \n"
    ". x . x . . x . \n";
  GomokuBoard board;
  board.FromString(str_board);
  uint64 explored;
  EXPECT_FALSE(DFPNS(board, &explored));
  cout << "Explored " << explored << "\n";
}

TEST(DFPNS, TrickyIWonder4) {
  const char *str_board = 
    ". x x o x . o o \n"
    ". . o x . x x o \n"
    ". o . x . . o x \n"
    ". . o . x o x o \n"
    "x o x x . . o . \n"
    ". . o . x o . . \n"
    "o . . . o x . x \n"
    ". x . x . . x . \n";
  GomokuBoard board;
  board.FromString(str_board);
  uint64 explored;
  EXPECT_TRUE(DFPNS(board, &explored));
  cout << "Explored " << explored << "\n";
}
